<?php
declare(strict_types=1);

namespace app\common\job;

use app\common\service\word\WordService;
use ba\Exception;
use think\db\exception\PDOException;
use think\exception\ValidateException;
use think\facade\Log;
use think\queue\Job;

set_time_limit(0);
class SayWordVocalRunner
{
    public function fire(Job $job, array $data): void
    {
        try {
            logSave([
                'file' => __FILE__,
                'message' => 'WordVocalRunner Exec',
                'data' => $data,
                'start_time' => date('Y-m-d H:i:s')
            ], 'WordVocalRunner');

            $wordService = new WordService();
            // 执行批量语音合成任务
            $result = $wordService->sayVocalSynthesis();
            if ($result) { // 修改判断条件，允许处理0条记录的情况
                $job->delete();
                logSave([
                    'file' => __FILE__,
                    'message' => 'WordVocalRunner finished',
                    'data' => $data,
                    'end_time' => date('Y-m-d H:i:s')
                ], 'WordVocalRunner');
            } else {
                $this->handleFailure($job, $data);
            }
        } catch (Exception|PDOException|ValidateException $e) {
            logSave([
                'file' => __FILE__,
                'message' => 'WordVocalRunner error',
                'data' => $data,
                'error' => $e->getMessage(),
                'line' => $e->getLine(),
                'errorFile' => $e->getFile(),
            ], 'WordVocalRunner');
            $this->handleFailure($job, $data);
        } catch (\Exception $e) {
            logSave([
                'file' => __FILE__,
                'message' => 'WordRunner Exception',
                'data' => $data,
                'error' => $e->getMessage(),
                'line' => $e->getLine(),
                'errorFile' => $e->getFile(),
            ], 'WordVocalRunner');
            $this->handleFailure($job, $data);
        } catch (\Throwable $t) {
            // 捕获致命错误
            $this->handleFailure($job, $data);
            logSave([
                'file' => __FILE__,
                'message' => 'WordRunner Throwable',
                'error' => $t->getMessage(),
                'line' => $t->getLine(),
                'errorFile' => $t->getFile(),
            ], 'WordVocalRunner');
        }
    }

    /**
     * 处理任务失败情况
     */
    private function handleFailure(Job $job, array $data): void
    {
        $attempts = $job->attempts();

        // 如果重试次数超过3次，则删除任务并记录失败
        if ($attempts > 3) {
            $job->delete();
            logSave([
                'file' => __FILE__,
                'message' => "队列任务失败超过3次，已删除",
                'data' => $data,
                'attempts' => $attempts,
                'end_time' => date('Y-m-d H:i:s')
            ], 'wordRunner');
        } else {
            // 延迟重试，避免频繁重试
            $job->release(60 * $attempts); // 递增延迟重试
            logSave([
                'file' => __FILE__,
                'message' => "队列任务失败，将自动重试",
                'data' => $data,
                'attempts' => $attempts,
            ], 'wordRunner');
        }
    }

    /**
     * 任务失败回调
     */
    public function failed(array $data): void
    {
        // 记录失败任务日志
        Log::error('队列任务最终失败', $data);
    }
}

